﻿' LibWowAPI
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports Newtonsoft.Json
Imports roncliProductions.LibWowAPI.Enums
Imports roncliProductions.LibWowAPI.Extensions
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Linq

Namespace roncliProductions.LibWowAPI.Guild

    ''' <summary>
    ''' A class that retrieves guild profile information from the Blizzard WoW API.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class GuildProfile
        Inherits WowAPIData

        Private gpGuild As New Schema.guild

#Region "WowAPIData Overrides"

        Protected Overrides ReadOnly Property URI As Uri
            Get
                QueryString.Clear()
                If Not String.IsNullOrWhiteSpace(FieldList) Then
                    QueryString.Add("fields", FieldList)
                End If
                Return New Uri(String.Format(CultureInfo.InvariantCulture, "/api/wow/guild/{0}/{1}", Options.Realm, Options.Name), UriKind.Relative)
            End Get
        End Property

        Protected Overrides ReadOnly Property CacheKey As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "LibWowAPI.GuildProfile.{0}.{1}.{2}", Options.Realm, Options.Name, FieldList)
            End Get
        End Property

#End Region

#Region "Properties"

#Region "Public"

        ''' <summary>
        ''' The options for looking up guild profile information.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Options As New GuildProfileOptions

        Private gGuild As Guild
        ''' <summary>
        ''' Guild profile information as returned from the Blizzard WoW API.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Guild As Guild
            Get
                Return gGuild
            End Get
        End Property

#End Region

#Region "Private"

        Private ReadOnly Property FieldList As String
            Get
                Dim lstFields As New List(Of String)
                If Options.Members Then lstFields.Add("members")
                If Options.Achievements Then lstFields.Add("achievements")
                Return String.Join(",", lstFields)
            End Get
        End Property

#End Region

#End Region

#Region "Methods"

#Region "Public"

#Region "Constructors"

        ''' <summary>
        ''' A default constructor to retrieve guild profile information from the Blizzard WoW API.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve a guild's profile.
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(strRealm As String, strName As String)
            Options.Realm = strRealm
            Options.Name = strName
            Load()
        End Sub

#End Region

        ''' <summary>
        ''' Loads the guild profile.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            MyBase.Retrieve()
            gpGuild = CType(JsonConvert.DeserializeObject(Data, GetType(Schema.guild)), Schema.guild)
            gGuild = New Guild(
                gpGuild.lastModified.BlizzardTimestampToUTC(),
                gpGuild.name,
                gpGuild.realm,
                gpGuild.level,
                CType(gpGuild.side, Side),
                gpGuild.achievementPoints,
                If(gpGuild.achievements Is Nothing, Nothing, SetAchievements(gpGuild.achievements)),
                If(gpGuild.members Is Nothing OrElse gpGuild.members.Count = 0, Nothing,
                    (From m In gpGuild.members
                    Select New Member(
                        New Character(
                            m.character.name,
                            m.character.realm,
                            m.character.class.GetClass(),
                            m.character.race.GetRace(),
                            CType(m.character.gender, Gender),
                            m.character.level,
                            m.character.achievementPoints,
                            m.character.thumbnail
                            ),
                        m.rank
                        )
                    ).ToCollection()
                    ),
                New Emblem(
                    gpGuild.emblem.icon,
                    gpGuild.emblem.iconColor.ArgbHexToColor(),
                    gpGuild.emblem.border,
                    gpGuild.emblem.borderColor.ArgbHexToColor(),
                    gpGuild.emblem.backgroundColor.ArgbHexToColor()
                    )
                )
        End Sub

#End Region

#Region "Private"

        Private Shared Function SetAchievements(aAchievements As Schema.achievements) As Achievements
            Dim colAchievements As New Collection(Of Achievement)
            Dim enumAchievement = aAchievements.achievementsCompleted.GetEnumerator()
            Dim enumAchievementTimestamp = aAchievements.achievementsCompletedTimestamp.GetEnumerator()
            While enumAchievement.MoveNext() And enumAchievementTimestamp.MoveNext()
                colAchievements.Add(New Achievement(CInt(enumAchievement.Current), CLng(enumAchievementTimestamp.Current).BlizzardTimestampToUTC()))
            End While

            Dim colCriteria As New Collection(Of Criteria)
            Dim enumCriteria = aAchievements.criteria.GetEnumerator()
            Dim enumCriteriaQuantity = aAchievements.criteriaQuantity.GetEnumerator()
            Dim enumCriteriaTimestamp = aAchievements.criteriaTimestamp.GetEnumerator()
            Dim enumCriteriaCreated = aAchievements.criteriaCreated.GetEnumerator()
            While enumCriteria.MoveNext() And enumCriteriaCreated.MoveNext() And enumCriteriaQuantity.MoveNext() And enumCriteriaTimestamp.MoveNext()
                colCriteria.Add(New Criteria(
                                CInt(enumCriteria.Current),
                                CLng(enumCriteriaQuantity.Current),
                                CLng(enumCriteriaTimestamp.Current).BlizzardTimestampToUTC(),
                                CLng(enumCriteriaCreated.Current).BlizzardTimestampToUTC()
                                ))
            End While

            Return New Achievements(colAchievements, colCriteria)
        End Function

#End Region

#End Region

    End Class

End Namespace